package com.kantboot.db.common.service.impl;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.kantboot.db.common.dto.CreateDatabaseDTO;
import com.kantboot.db.common.exception.NoDatabaseUrlException;
import com.kantboot.db.common.exception.NonExistentDatabaseException;
import com.kantboot.db.common.service.IDbCommonService;
import org.springframework.stereotype.Service;

@Service
public class DbCommonServiceImpl implements IDbCommonService {

    /**
     * 生成全局配置
     *
     * @param createDatabaseDTO
     * @return
     */
    private GlobalConfig createGlobalConfig
    (CreateDatabaseDTO createDatabaseDTO) {
        return new GlobalConfig()
                .setOutputDir(createDatabaseDTO.getOutputDir()) // 代码生成路径
                .setAuthor(createDatabaseDTO.getAuthor()) // 类上面的作者
                .setOpen(createDatabaseDTO.getIsOpenResourceManager() == 1) // 是否生成后是否打开资源管理器
                .setFileOverride(createDatabaseDTO.getIsFileOverride() == 1) // 是否重新生成时文件是否覆盖
                .setIdType(IdType.values()[createDatabaseDTO.getIdType()]) // 主键策略
                .setSwagger2(createDatabaseDTO.getIsSwagger() == 1) // 是否开启Swagger2模式
                .setServiceName("%sService")
                .setDateType(DateType.ONLY_DATE);
    }

    /**
     * 数据源配置
     *
     * @param createDatabaseDTO
     * @return
     */
    private DataSourceConfig createDataSourceConfig
    (CreateDatabaseDTO createDatabaseDTO) {
        return new DataSourceConfig()
                .setUrl(createDatabaseDTO.getDatabaseUrl()) //数据库连接地址
                .setDriverName(createDatabaseDTO.getDatabaseDriverName()) //数据库驱动名
                .setUsername(createDatabaseDTO.getDatabaseUsername()) //数据库账号
                .setPassword(createDatabaseDTO.getDatabasePassword()) //数据库密码
                .setDbType(DbType.MYSQL);
    }

    /**
     * 包名配置
     */
    private PackageConfig createPackageConfigConfig(CreateDatabaseDTO createDatabaseDTO) {
        return new PackageConfig()
                .setModuleName(createDatabaseDTO.getPackageModuleName()) //模块名
                .setParent(createDatabaseDTO.getPackageParentName())
                .setController(createDatabaseDTO.getPackageControllerName())
                .setEntity(createDatabaseDTO.getPackageEntityName())
                .setService(createDatabaseDTO.getPackageServiceName())
                .setMapper(createDatabaseDTO.getPackageMapperName());
    }

    /**
     * 策略配置
     */
    private StrategyConfig createStrategyConfig() {
        return new StrategyConfig()
                .setNaming(NamingStrategy.underline_to_camel) //数据库表映射到实体的命名策略
                .setColumnNaming(NamingStrategy.underline_to_camel)//数据库表字段映射到实体的命名策略
                .setEntityLombokModel(true) // lombok 模型 @Accessors(chain = true) setter链式操作
                .setRestControllerStyle(true) //restful api风格控制器
                .setControllerMappingHyphenStyle(true); //url中驼峰转连字符
    }

    /**
     * 进行代码生成
     * @param createDatabaseDTO
     * @return
     */
    @Override
    public void toGenerator(CreateDatabaseDTO createDatabaseDTO){

        if(createDatabaseDTO.getDatabaseUrl() == null
                || createDatabaseDTO.getDatabaseUrl().equals("")
        )
            //数据库连接地址不可为空
            throw new NoDatabaseUrlException();

        try{
            new AutoGenerator()
                    .setGlobalConfig(createGlobalConfig(createDatabaseDTO))
                    .setDataSource(createDataSourceConfig(createDatabaseDTO))
                    .setPackageInfo(createPackageConfigConfig(createDatabaseDTO))
                    .setStrategy(createStrategyConfig())
                    .execute();
        }
        catch (RuntimeException e){
            String eMessage=e.getMessage();
            if(eMessage.
                    indexOf("java.sql.SQLSyntaxErrorException: " +
                            "Unknown database ")!=-1)
                //数据库不存在
                throw new NonExistentDatabaseException()
                        .setDatabaseName(
                                eMessage.substring(("java.sql.SQLSyntaxErrorException: " +
                                        "Unknown database ").length()));
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}
